import { Injectable, inject } from '@angular/core';
import { InMemoryDbService, RequestInfo, ResponseOptions } from 'angular-in-memory-web-api';
import { AuthUser } from '@shared/models/user.models';
import { LoginRequest, LoginResponse } from '@shared/models/login.models';
import { MockHelpService } from './mock-help.service';
import { Observable, tap } from 'rxjs';

/**
 * 模拟数据服务
 * 统一管理所有模拟数据，包括用户、认证、业务数据等
 */
@Injectable({
  providedIn: 'root'
})
export class MockDataService implements InMemoryDbService {

  private readonly mockHelpService = inject(MockHelpService);

  /**
   * 创建模拟数据库
   * 统一管理所有模拟数据
   */
  createDb() {
    return {
      // 用户相关数据
      users: this.getMockUsers(),
      credentials: this.getMockCredentials(),
      
      // 业务数据（可根据需要扩展）
      // products: this.getMockProducts(),
      // orders: this.getMockOrders(),
      // settings: this.getMockSettings(),
    };
  }

  /**
   * 生成 ID（如果需要）
   */
  genId<T extends { id: any }>(collection: T[], collectionName: string): any {
    if (collection.length > 0) {
      const maxId = Math.max(...collection.map(item => typeof item.id === 'number' ? item.id : 0));
      return maxId + 1;
    }
    return 1;
  }

  /**
   * 处理 GET 请求
   */
  get(reqInfo: RequestInfo) {
    return this.post(reqInfo); // 复用 POST 方法的逻辑
  }

  /**
   * 处理 HTTP 请求
   * 拦截认证相关的 API 请求并提供模拟响应
   */
  post(reqInfo: RequestInfo) {
    const { url, req } = reqInfo;
  
    if (!url.startsWith('/api/')) {
      return undefined;
    }

    // 获取对应的处理方法
    let response$: Observable<ResponseOptions> | undefined;
  
    if (url.includes('/api/auth/login')) {
      response$ = this.handleLogin(reqInfo);
    } else if (url.includes('/api/auth/token')) {
      response$ = this.handleTokenRefresh(reqInfo);
    } else if (url.includes('/api/auth/logout')) {
      response$ = this.handleLogout(reqInfo);
    } else if (url.includes('/api/user/profile')) {
      response$ = this.handleUserProfile(reqInfo);
    }
  
    if (response$) {
      // 直接订阅并记录
      response$.subscribe({
        next: (response: ResponseOptions) => {
          this.mockHelpService.logHttp(reqInfo, response);
        },
        error: (error) => {
          // 即使出错也要记录请求
          this.mockHelpService.logHttp(reqInfo, error);
        }
      });
      
      return response$;
    }
  
    return undefined;
  }

  /**
   * 处理登录请求
   */
  private handleLogin(reqInfo: RequestInfo) {
    const loginRequest: LoginRequest = (reqInfo.req as any).body as LoginRequest;

    // 查找匹配的用户凭据
    const credentials = this.getMockCredentials();
    const credential = credentials.find(
      c => c.username === loginRequest.username && c.password === loginRequest.password
    );

    if (credential) {
      // 找到匹配的用户
      const users = this.getMockUsers();
      const user = users.find(u => u.id === credential.userId);

      if (user) {
        // 生成模拟 JWT Token
        const token = this.generateMockJwtToken(user);
        const refreshToken = this.generateMockRefreshToken();

        const response: LoginResponse = {
          token,
          refreshToken
        };

        return reqInfo.utils.createResponse$(() => ({
          status: 200,
          headers: reqInfo.headers,
          url: reqInfo.url,
          body: response
        }));
      }
    }

    // 登录失败 - 只有在没有找到匹配凭据时才执行
    return reqInfo.utils.createResponse$(() => ({
      status: 401,
      headers: reqInfo.headers,
      url: reqInfo.url,
      body: { 
        error: 'Invalid credentials',
        message: '用户名或密码错误',
        timestamp: new Date().toISOString()
      }
    }));
  }

  /**
   * 处理 Token 刷新请求
   */
  private handleTokenRefresh(reqInfo: RequestInfo) {
    const refreshRequest = (reqInfo.req as any).body as { refreshToken: string };

    // 简单的刷新逻辑：生成新的 Token
    if (refreshRequest.refreshToken) {
      const newToken = this.generateMockJwtToken();
      const newRefreshToken = this.generateMockRefreshToken();

      const response: LoginResponse = {
        token: newToken,
        refreshToken: newRefreshToken
      };

      return reqInfo.utils.createResponse$(() => ({
        status: 200,
        headers: reqInfo.headers,
        url: reqInfo.url,
        body: response
      }));
    }

    // 刷新失败
    return reqInfo.utils.createResponse$(() => ({
      status: 401,
      headers: reqInfo.headers,
      url: reqInfo.url,
      body: { 
        error: 'Invalid refresh token',
        message: '刷新令牌无效或已过期',
        timestamp: new Date().toISOString()
      }
    }));
  }

  /**
   * 处理登出请求
   */
  private handleLogout(reqInfo: RequestInfo) {
    return reqInfo.utils.createResponse$(() => ({
      status: 200,
      headers: reqInfo.headers,
      url: reqInfo.url,
      body: { message: 'Logged out successfully' }
    }));
  }

  /**
   * 生成模拟 JWT Token
   */
  private generateMockJwtToken(user?: AuthUser): string {
    // 创建 JWT Header
    const header = {
      alg: 'HS256',
      typ: 'JWT'
    };
    
    // 创建 JWT Payload
    const payload = {
      sub: user?.id || '1',
      username: user?.username || 'admin',
      email: user?.email || 'admin@example.com',
      firstName: user?.firstName || 'Admin',
      lastName: user?.lastName || 'User',
      avatar: user?.avatar,
      iat: Math.floor(Date.now() / 1000),
      exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1小时过期
    };

    // 安全地编码 Header 和 Payload
    const encodedHeader = this.base64UrlEncode(JSON.stringify(header));
    const encodedPayload = this.base64UrlEncode(JSON.stringify(payload));
    
    // 创建签名（模拟）
    const signature = this.base64UrlEncode('mock-signature');

        const token = `${encodedHeader}.${encodedPayload}.${signature}`;
        
        return token;
  }

  /**
   * Base64 URL 安全编码
   */
  private base64UrlEncode(str: string): string {
    // 使用 btoa 进行 base64 编码
    const base64 = btoa(unescape(encodeURIComponent(str)));
    // 转换为 URL 安全的 base64
    return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
  }

  /**
   * 生成模拟 Refresh Token
   */
  private generateMockRefreshToken(): string {
    return 'mock-refresh-token-' + Math.random().toString(36).substr(2, 9);
  }

  /**
   * 生成 SVG 头像
   */
  private generateAvatarSVG(text: string, color: string): string {
    const svg = `
      <svg width="150" height="150" viewBox="0 0 150 150" xmlns="http://www.w3.org/2000/svg">
        <circle cx="75" cy="75" r="75" fill="${color}"/>
        <text x="75" y="95" text-anchor="middle" fill="white" font-family="Arial, sans-serif" font-size="60" font-weight="bold">${text}</text>
      </svg>
    `;
    return 'data:image/svg+xml;base64,' + btoa(svg);
  }

  /**
   * 获取模拟用户数据
   */
  private getMockUsers(): AuthUser[] {
    return [
      {
        id: '1',
        username: 'admin',
        email: 'admin@example.com',
        firstName: 'Admin',
        lastName: 'User',
        avatar: this.generateAvatarSVG('A', '#007bff')
      },
      {
        id: '2',
        username: 'user',
        email: 'user@example.com',
        firstName: 'Normal',
        lastName: 'User',
        avatar: this.generateAvatarSVG('U', '#28a745')
      },
      {
        id: '3',
        username: 'demo',
        email: 'demo@example.com',
        firstName: 'Demo',
        lastName: 'Account',
        avatar: this.generateAvatarSVG('D', '#ffc107')
      }
    ];
  }

  /**
   * 获取模拟登录凭据
   */
  private getMockCredentials() {
    return [
      {
        id: '1',
        username: 'admin',
        password: 'admin123',
        userId: '1',
        role: 'admin'
      },
      {
        id: '2',
        username: 'user',
        password: 'user123',
        userId: '2',
        role: 'user'
      },
      {
        id: '3',
        username: 'demo',
        password: 'demo123',
        userId: '3',
        role: 'demo'
      }
    ];
  }

  /**
   * 获取模拟产品数据（示例）
   */
  private getMockProducts() {
    return [
      {
        id: '1',
        name: '产品A',
        price: 100,
        category: '电子产品',
        description: '这是一个示例产品'
      },
      {
        id: '2',
        name: '产品B',
        price: 200,
        category: '家居用品',
        description: '这是另一个示例产品'
      }
    ];
  }

  /**
   * 获取模拟订单数据（示例）
   */
  private getMockOrders() {
    return [
      {
        id: '1',
        userId: '1',
        productId: '1',
        quantity: 2,
        total: 200,
        status: 'completed',
        createdAt: new Date().toISOString()
      }
    ];
  }

  /**
   * 获取模拟设置数据（示例）
   */
  private getMockSettings() {
    return [
      {
        id: '1',
        key: 'theme',
        value: 'light',
        description: '主题设置'
      },
      {
        id: '2',
        key: 'language',
        value: 'zh_CN',
        description: '语言设置'
      }
    ];
  }

  /**
   * 处理用户信息请求
   * 这个请求需要认证，会检查 Authorization 头
   */
  private handleUserProfile(reqInfo: RequestInfo) {
    // 检查 Authorization 头
    let authHeader = null;
    
    // 方法1：尝试直接从 headers 获取
    authHeader = reqInfo.headers.get('Authorization') || reqInfo.headers.get('X-Authorization');
    
    // 方法2：尝试从 reqInfo.req 中获取（类型断言）
    if (!authHeader && reqInfo.req) {
      const req = reqInfo.req as any;
      if (req.headers) {
        authHeader = req.headers.get('Authorization') || req.headers.get('X-Authorization');
      }
    }
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return reqInfo.utils.createResponse$(() => ({
        status: 401,
        headers: reqInfo.headers,
        url: reqInfo.url,
        body: { 
          error: 'Unauthorized',
          message: '缺少或无效的认证头',
          timestamp: new Date().toISOString()
        }
      }));
    }

    // 模拟用户信息响应
    const userProfile: AuthUser = {
      id: '1',
      username: 'admin',
      email: 'admin@example.com',
      firstName: 'Admin',
      lastName: 'User',
      avatar: this.generateAvatarSVG('A', '#1976d2')
    };

    return reqInfo.utils.createResponse$(() => ({
      status: 200,
      headers: reqInfo.headers,
      url: reqInfo.url,
      body: userProfile
    }));
  }
}
